﻿
namespace HSS.Xaml.UI.Media
{
	#region Using Directives
	using System;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;
	using System.Globalization;
	using System.Reflection;
	using System.Windows.Media;
	#endregion

	#region KnownColors
	/// <summary>
	/// 
	/// </summary>
	public static class KnownColors
	{
		/// <summary>
		/// Converts a HexColor String (#FFAABBCC) to a System.Windows.Media.Color.
		/// </summary>
		/// <param name="hexColor">The hex color string.</param>
		/// <returns>The Color.</returns>
		public static Color HexColorToColor(string hexColor)
		{
			if (hexColor != null)
			{
				hexColor = hexColor.Replace("#", "");
				byte r = System.Convert.ToByte(hexColor.Substring(0, 2), 16);
				byte g = System.Convert.ToByte(hexColor.Substring(2, 2), 16);
				byte b = System.Convert.ToByte(hexColor.Substring(4, 2), 16);

				return Color.FromArgb(System.Convert.ToByte(255), r, g, b);
			}
			else
				return Color.FromArgb(System.Convert.ToByte(255), 0, 0, 0);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="value"></param>
		/// <returns></returns>
		public static SolidColorBrush ColorStringToKnownBrush(string value)
		{
			if (value != null)
			{
				var color = ColorStringToKnownColor(value);
				if (color != KnownColor.UnknownColor)
					return (SolidColorBrush)color;
			}
			return null;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="argb"></param>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "argb")]
		public static SolidColorBrush SolidColorBrushFromInt64(Int64 argb)
		{
			SolidColorBrush brush = null;
			lock (brushCache)
			{
				if (!brushCache.TryGetValue(argb, out brush))
				{
					brush = (SolidColorBrush)(KnownColor)argb;
					brushCache[argb] = brush;
				}
			}
			return brush;
		}
		/// <summary>
		/// 
		/// </summary>
		public static Collection<object> KnownColorsList
		{
			get
			{
				if (null == knownColorsList)
				{
					knownColorsList = new Collection<object>();
					var flags = BindingFlags.Public | BindingFlags.Static;
					foreach (var field in typeof(KnownColor).GetFields(flags))
						knownColorsList.Add(field.GetValue(null));
				}
				return knownColorsList;
			}
		} static Collection<object> knownColorsList;
		/// <summary>
		/// 
		/// </summary>
		/// <param name="color"></param>
		/// <returns></returns>
		public static KnownColor KnownColorFromColor(Color color)
		{
			var colorString = color.ToString(System.Globalization.CultureInfo.InvariantCulture);
			colorString = colorString.Replace("#", "");
			var knownColorInt64 = long.Parse(colorString, NumberStyles.AllowHexSpecifier, System.Globalization.CultureInfo.InvariantCulture);
			return new KnownColor(knownColorInt64);
		}

		private static Dictionary<Int64, SolidColorBrush> brushCache = new Dictionary<Int64, SolidColorBrush>();

		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
		internal static KnownColor ColorStringToKnownColor(string colorString)
		{
			if (colorString != null)
			{
				var str = colorString.ToUpper(CultureInfo.InvariantCulture);
				switch (str.Length)
				{
					case 3:
						if (!str.Equals("RED"))
						{
							if (!str.Equals("TAN"))
							{
								break;
							}
							return (KnownColor)(-2968436);
						}
						return (KnownColor)(-65536);

					case 4:
						switch (str[0])
						{
							case 'A':
								if (!str.Equals("AQUA"))
								{
									break;
								}
								return (KnownColor)(-16711681);

							case 'B':
								if (!str.Equals("BLUE"))
								{
									break;
								}
								return (KnownColor)(-16776961);

							case 'C':
								if (!str.Equals("CYAN"))
								{
									break;
								}
								return (KnownColor)(-16711681);

							case 'G':
								if (str.Equals("GOLD"))
								{
									return (KnownColor)(-10496);
								}
								if (!str.Equals("GRAY"))
								{
									break;
								}
								return (KnownColor)(-8355712);

							case 'L':
								if (!str.Equals("LIME"))
								{
									break;
								}
								return (KnownColor)(-16711936);

							case 'N':
								if (!str.Equals("NAVY"))
								{
									break;
								}
								return (KnownColor)(-16777088);

							case 'P':
								if (str.Equals("PERU"))
								{
									return (KnownColor)(-3308225);
								}
								if (str.Equals("PINK"))
								{
									return (KnownColor)(-16181);
								}
								if (!str.Equals("PLUM"))
								{
									break;
								}
								return (KnownColor)(-2252579);

							case 'S':
								if (!str.Equals("SNOW"))
								{
									break;
								}
								return (KnownColor)(-1286);

							case 'T':
								if (!str.Equals("TEAL"))
								{
									break;
								}
								return (KnownColor)(-16744320);
						}
						break;

					case 5:
						switch (str[0])
						{
							case 'A':
								if (!str.Equals("AZURE"))
								{
									break;
								}
								return (KnownColor)(-983041);

							case 'B':
								if (str.Equals("BEIGE"))
								{
									return (KnownColor)(-657956);
								}
								if (str.Equals("BLACK"))
								{
									return ~KnownColor.Transparent;
								}
								if (!str.Equals("BROWN"))
								{
									break;
								}
								return (KnownColor)(-5952982);

							case 'C':
								if (!str.Equals("CORAL"))
								{
									break;
								}
								return (KnownColor)(-32944);

							case 'G':
								if (!str.Equals("GREEN"))
								{
									break;
								}
								return (KnownColor)(-16744448);

							case 'I':
								if (!str.Equals("IVORY"))
								{
									break;
								}
								return (KnownColor)(-16);

							case 'K':
								if (!str.Equals("KHAKI"))
								{
									break;
								}
								return (KnownColor)(-989556);

							case 'L':
								if (!str.Equals("LINEN"))
								{
									break;
								}
								return (KnownColor)(-331546);

							case 'O':
								if (!str.Equals("OLIVE"))
								{
									break;
								}
								return (KnownColor)(-8355840);

							case 'W':
								if (str.Equals("WHEAT"))
								{
									return (KnownColor)(-663885);
								}
								if (!str.Equals("WHITE"))
								{
									break;
								}
								return (KnownColor)(-1);
						}
						break;

					case 6:
						switch (str[0])
						{
							case 'M':
								if (!str.Equals("MAROON"))
								{
									break;
								}
								return (KnownColor)(-8388608);

							case 'O':
								if (str.Equals("ORANGE"))
								{
									return (KnownColor)(-23296);
								}
								if (!str.Equals("ORCHID"))
								{
									break;
								}
								return (KnownColor)(-2461482);

							case 'P':
								if (!str.Equals("PURPLE"))
								{
									break;
								}
								return (KnownColor)(-8388480);

							case 'S':
								if (str.Equals("SALMON"))
								{
									return (KnownColor)(-360334);
								}
								if (str.Equals("SIENNA"))
								{
									return (KnownColor)(-6270419);
								}
								if (!str.Equals("SILVER"))
								{
									break;
								}
								return (KnownColor)(-4144960);

							case 'T':
								if (!str.Equals("TOMATO"))
								{
									break;
								}
								return (KnownColor)(-40121);

							case 'V':
								if (!str.Equals("VIOLET"))
								{
									break;
								}
								return (KnownColor)(-1146130);

							case 'Y':
								if (!str.Equals("YELLOW"))
								{
									break;
								}
								return (KnownColor)(-256);

							case 'I':
								if (!str.Equals("INDIGO"))
								{
									break;
								}
								return (KnownColor)(-11861886);

							case 'B':
								if (!str.Equals("BISQUE"))
								{
									break;
								}
								return (KnownColor)(-6972);
						}
						break;

					case 7:
						switch (str[0])
						{
							case 'C':
								if (!str.Equals("CRIMSON"))
								{
									break;
								}
								return (KnownColor)(-2354116);

							case 'D':
								if (str.Equals("DARKRED"))
								{
									return (KnownColor)(-7667712);
								}
								if (!str.Equals("DIMGRAY"))
								{
									break;
								}
								return (KnownColor)(-9868951);

							case 'F':
								if (!str.Equals("FUCHSIA"))
								{
									break;
								}
								return (KnownColor)(-65281);

							case 'H':
								if (!str.Equals("HOTPINK"))
								{
									break;
								}
								return (KnownColor)(-38476);

							case 'M':
								if (!str.Equals("MAGENTA"))
								{
									break;
								}
								return (KnownColor)(-65281);

							case 'O':
								if (!str.Equals("OLDLACE"))
								{
									break;
								}
								return (KnownColor)(-133658);

							case 'S':
								if (!str.Equals("SKYBLUE"))
								{
									break;
								}
								return (KnownColor)(-7876885);

							case 'T':
								if (!str.Equals("THISTLE"))
								{
									break;
								}
								return (KnownColor)(-2572328);
						}
						break;

					case 8:
						{
							char ch3 = str[0];
							if (ch3 > 'H')
							{
								switch (ch3)
								{
									case 'L':
										if (!str.Equals("LAVENDER"))
										{
											break;
										}
										return (KnownColor)(-1644806);

									case 'M':
										if (!str.Equals("MOCCASIN"))
										{
											break;
										}
										return (KnownColor)(-6987);

									case 'S':
										if (str.Equals("SEAGREEN"))
										{
											return (KnownColor)(-13726889);
										}
										if (!str.Equals("SEASHELL"))
										{
											break;
										}
										return (KnownColor)(-2578);
								}
								break;
							}
							switch (ch3)
							{
								case 'C':
									if (!str.Equals("CORNSILK"))
									{
										break;
									}
									return (KnownColor)(-1828);

								case 'D':
									if (str.Equals("DARKBLUE"))
									{
										return (KnownColor)(-16777077);
									}
									if (str.Equals("DARKCYAN"))
									{
										return (KnownColor)(-16741493);
									}
									if (str.Equals("DARKGRAY"))
									{
										return (KnownColor)(-5658199);
									}
									if (!str.Equals("DEEPPINK"))
									{
										break;
									}
									return (KnownColor)(-60269);

								case 'H':
									if (!str.Equals("HONEYDEW"))
									{
										break;
									}
									return (KnownColor)(-983056);
							}
							break;
						}
					case 9:
						switch (str[0])
						{
							case 'A':
								if (!str.Equals("ALICEBLUE"))
								{
									break;
								}
								return (KnownColor)(-984833);

							case 'B':
								if (!str.Equals("BURLYWOOD"))
								{
									break;
								}
								return (KnownColor)(-2180985);

							case 'C':
								if (str.Equals("CADETBLUE"))
								{
									return (KnownColor)(-10510688);
								}
								if (!str.Equals("CHOCOLATE"))
								{
									break;
								}
								return (KnownColor)(-2987746);

							case 'D':
								if (str.Equals("DARKGREEN"))
								{
									return (KnownColor)(-16751616);
								}
								if (!str.Equals("DARKKHAKI"))
								{
									break;
								}
								return (KnownColor)(-4343957);

							case 'F':
								if (!str.Equals("FIREBRICK"))
								{
									break;
								}
								return (KnownColor)(-5103070);

							case 'G':
								if (str.Equals("GAINSBORO"))
								{
									return (KnownColor)(-2302756);
								}
								if (!str.Equals("GOLDENROD"))
								{
									break;
								}
								return (KnownColor)(-2448096);

							case 'I':
								if (!str.Equals("INDIANRED"))
								{
									break;
								}
								return (KnownColor)(-3318692);

							case 'L':
								if (str.Equals("LAWNGREEN"))
								{
									return (KnownColor)(-8586240);
								}
								if (str.Equals("LIGHTBLUE"))
								{
									return (KnownColor)(-5383962);
								}
								if (str.Equals("LIGHTCYAN"))
								{
									return (KnownColor)(-2031617);
								}
								if (str.Equals("LIGHTGRAY"))
								{
									return (KnownColor)(-2894893);
								}
								if (str.Equals("LIGHTPINK"))
								{
									return (KnownColor)(-18751);
								}
								if (!str.Equals("LIMEGREEN"))
								{
									break;
								}
								return (KnownColor)(-13447886);

							case 'M':
								if (str.Equals("MINTCREAM"))
								{
									return (KnownColor)(-655366);
								}
								if (!str.Equals("MISTYROSE"))
								{
									break;
								}
								return (KnownColor)(-6943);

							case 'O':
								if (str.Equals("OLIVEDRAB"))
								{
									return (KnownColor)(-9728477);
								}
								if (!str.Equals("ORANGERED"))
								{
									break;
								}
								return (KnownColor)(-47872);

							case 'P':
								if (str.Equals("PALEGREEN"))
								{
									return (KnownColor)(-6751336);
								}
								if (!str.Equals("PEACHPUFF"))
								{
									break;
								}
								return (KnownColor)(-9543);

							case 'R':
								if (str.Equals("ROSYBROWN"))
								{
									return (KnownColor)(-4419697);
								}
								if (!str.Equals("ROYALBLUE"))
								{
									break;
								}
								return (KnownColor)(-12490271);

							case 'S':
								if (str.Equals("SLATEBLUE"))
								{
									return (KnownColor)(-9807155);
								}
								if (str.Equals("SLATEGRAY"))
								{
									return (KnownColor)(-9404272);
								}
								if (!str.Equals("STEELBLUE"))
								{
									break;
								}
								return (KnownColor)(-12156236);

							case 'T':
								if (!str.Equals("TURQUOISE"))
								{
									break;
								}
								return (KnownColor)(-12525360);
						}
						break;

					case 10:
						{
							char ch2 = str[0];
							if (ch2 > 'P')
							{
								switch (ch2)
								{
									case 'S':
										if (!str.Equals("SANDYBROWN"))
										{
											break;
										}
										return (KnownColor)(-744352);

									case 'W':
										if (!str.Equals("WHITESMOKE"))
										{
											break;
										}
										return (KnownColor)(-657931);
								}
								break;
							}
							switch (ch2)
							{
								case 'A':
									if (!str.Equals("AQUAMARINE"))
									{
										break;
									}
									return (KnownColor)(-8388652);

								case 'B':
									if (!str.Equals("BLUEVIOLET"))
									{
										break;
									}
									return (KnownColor)(-7722014);

								case 'C':
									if (!str.Equals("CHARTREUSE"))
									{
										break;
									}
									return (KnownColor)(-8388864);

								case 'D':
									if (str.Equals("DARKORANGE"))
									{
										return (KnownColor)(-29696);
									}
									if (str.Equals("DARKORCHID"))
									{
										return (KnownColor)(-6737204);
									}
									if (str.Equals("DARKSALMON"))
									{
										return (KnownColor)(-1468806);
									}
									if (str.Equals("DARKVIOLET"))
									{
										return (KnownColor)(-7077677);
									}
									if (!str.Equals("DODGERBLUE"))
									{
										break;
									}
									return (KnownColor)(-14774017);

								case 'G':
									if (!str.Equals("GHOSTWHITE"))
									{
										break;
									}
									return (KnownColor)(-460545);

								case 'L':
									if (str.Equals("LIGHTCORAL"))
									{
										return (KnownColor)(-1015680);
									}
									if (!str.Equals("LIGHTGREEN"))
									{
										break;
									}
									return (KnownColor)(-7278960);

								case 'M':
									if (!str.Equals("MEDIUMBLUE"))
									{
										break;
									}
									return (KnownColor)(-16777011);

								case 'P':
									if (str.Equals("PAPAYAWHIP"))
									{
										return (KnownColor)(-4139);
									}
									if (!str.Equals("POWDERBLUE"))
									{
										break;
									}
									return (KnownColor)(-5185306);
							}
							break;
						}
					case 11:
						{
							char ch = str[0];
							if (ch > 'N')
							{
								switch (ch)
								{
									case 'S':
										if (!str.Equals("SADDLEBROWN"))
										{
											if (!str.Equals("SPRINGGREEN"))
											{
												break;
											}
											return (KnownColor)(-16711809);
										}
										return (KnownColor)(-7650029);

									case 'T':
										if (!str.Equals("TRANSPARENT"))
										{
											break;
										}
										return KnownColor.Transparent;

									case 'Y':
										if (!str.Equals("YELLOWGREEN"))
										{
											break;
										}
										return (KnownColor)(-6632142);
								}
								break;
							}
							switch (ch)
							{
								case 'D':
									if (str.Equals("DARKMAGENTA"))
									{
										return (KnownColor)(-7667573);
									}
									if (!str.Equals("DEEPSKYBLUE"))
									{
										break;
									}
									return (KnownColor)(-16728065);

								case 'F':
									if (str.Equals("FLORALWHITE"))
									{
										return (KnownColor)(-1296);
									}
									if (!str.Equals("FORESTGREEN"))
									{
										break;
									}
									return (KnownColor)(-14513374);

								case 'G':
									if (!str.Equals("GREENYELLOW"))
									{
										break;
									}
									return (KnownColor)(-5374161);

								case 'L':
									if (str.Equals("LIGHTSALMON"))
									{
										return (KnownColor)(-24454);
									}
									if (!str.Equals("LIGHTYELLOW"))
									{
										break;
									}
									return (KnownColor)(-32);

								case 'N':
									if (!str.Equals("NAVAJOWHITE"))
									{
										break;
									}
									return (KnownColor)(-8531);
							}
							break;
						}
					case 12:
						switch (str[0])
						{
							case 'L':
								if (str.Equals("LIGHTSKYBLUE"))
								{
									return (KnownColor)(-7876870);
								}
								if (!str.Equals("LEMONCHIFFON"))
								{
									break;
								}
								return (KnownColor)(-1331);

							case 'M':
								if (str.Equals("MEDIUMORCHID"))
								{
									return (KnownColor)(-4565549);
								}
								if (str.Equals("MEDIUMPURPLE"))
								{
									return (KnownColor)(-7114533);
								}
								if (!str.Equals("MIDNIGHTBLUE"))
								{
									break;
								}
								return (KnownColor)(-15132304);

							case 'D':
								if (!str.Equals("DARKSEAGREEN"))
								{
									break;
								}
								return (KnownColor)(-7357297);

							case 'A':
								if (!str.Equals("ANTIQUEWHITE"))
								{
									break;
								}
								return (KnownColor)(-332841);
						}
						break;

					case 13:
						switch (str[0])
						{
							case 'D':
								if (str.Equals("DARKSLATEBLUE"))
								{
									return (KnownColor)(-12042869);
								}
								if (str.Equals("DARKSLATEGRAY"))
								{
									return (KnownColor)(-13676721);
								}
								if (str.Equals("DARKGOLDENROD"))
								{
									return (KnownColor)(-4684277);
								}
								if (!str.Equals("DARKTURQUOISE"))
								{
									break;
								}
								return (KnownColor)(-16724271);

							case 'L':
								if (str.Equals("LIGHTSEAGREEN"))
								{
									return (KnownColor)(-14634326);
								}
								if (!str.Equals("LAVENDERBLUSH"))
								{
									break;
								}
								return (KnownColor)(-3851);

							case 'P':
								if (str.Equals("PALEGOLDENROD"))
								{
									return (KnownColor)(-1120086);
								}
								if (str.Equals("PALETURQUOISE"))
								{
									return (KnownColor)(-5247250);
								}
								if (!str.Equals("PALEVIOLETRED"))
								{
									break;
								}
								return (KnownColor)(-2396013);
						}
						break;

					case 14:
						switch (str[0])
						{
							case 'B':
								if (!str.Equals("BLANCHEDALMOND"))
								{
									break;
								}
								return (KnownColor)(-5171);

							case 'C':
								if (!str.Equals("CORNFLOWERBLUE"))
								{
									break;
								}
								return (KnownColor)(-10185235);

							case 'D':
								if (!str.Equals("DARKOLIVEGREEN"))
								{
									break;
								}
								return (KnownColor)(-11179217);

							case 'L':
								if (str.Equals("LIGHTSLATEGRAY"))
								{
									return (KnownColor)(-8943463);
								}
								if (!str.Equals("LIGHTSTEELBLUE"))
								{
									break;
								}
								return (KnownColor)(-5192482);

							case 'M':
								if (!str.Equals("MEDIUMSEAGREEN"))
								{
									break;
								}
								return (KnownColor)(-12799119);
						}
						break;

					case 15:
						if (!str.Equals("MEDIUMSLATEBLUE"))
						{
							if (str.Equals("MEDIUMTURQUOISE"))
							{
								return (KnownColor)(-12004916);
							}
							if (str.Equals("MEDIUMVIOLETRED"))
							{
								return (KnownColor)(-3730043);
							}
							break;
						}
						return (KnownColor)(-8689426);

					case 0x10:
						if (!str.Equals("MEDIUMAQUAMARINE"))
						{
							break;
						}
						return (KnownColor)(-10039894);

					case 0x11:
						if (!str.Equals("MEDIUMSPRINGGREEN"))
						{
							break;
						}
						return (KnownColor)(-16713062);

					case 20:
						if (!str.Equals("LIGHTGOLDENRODYELLOW"))
						{
							break;
						}
						return (KnownColor)(-329006);
				}
			}
			return KnownColor.UnknownColor;
		}

		internal static string MatchColor(string colorString, out bool isKnownColor, out bool isNumericColor)
		{
			string str = colorString.Trim();
			if ((((str.Length == 4) || (str.Length == 5)) || ((str.Length == 7) || (str.Length == 9))) && (str[0] == '#'))
			{
				isNumericColor = true;
				isKnownColor = false;
				return str;
			}
			isNumericColor = false;
			isKnownColor = true;
			return str;
		}

	}
	#endregion
}
